// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()
const db = cloud.database({
  throwOnNotFound: false
})
const _ = db.command
const $ = db.command.aggregate

async function transferBalance(payer_id, payee_id, num, remark) {
  const modified_time = new Date().getTime();
  const tran = await db.startTransaction();
  // check Price
  const payer = (await tran.collection('tb_balance').doc(payer_id).get()).data;
  if (payer.current_balance < num) return { errMsg: '金额不足以支付' }
  // compute changed balance
  const payer_balance = payer.current_balance - num;
  const payee_balance = (await tran.collection('tb_balance').doc(payee_id).get()).data.current_balance + num;
  // payer
  await tran.collection('tb_balance').doc(payer_id)
    .update({ data: { current_balance: _.inc(-num), modified_time } })
  // payee
  await tran.collection('tb_balance').doc(payee_id)
    .update({ data: { current_balance: _.inc(num), modified_time } })
  await tran.commit()
  await db.collection('tb_balance_change').add({
    data: {
      change_balance: num,
      payer_balance,
      payee_balance,
      modified_time,
      remark,
      payee_id,
      payer_id,
    }
  })
  return { errMsg: '' }
}

async function searchBalanceList(user_id, searchText, searchData) {
  let res = await db.collection('tb_balance').doc(user_id).get();
  if (!res.data) {
    await db.collection('tb_balance').add({
      data: {
        _id: user_id,
        current_balance: 0,
        modified_time: new Date().getTime()
      }
    })
    const transferRes = await transferBalance('<system>', user_id, 1000 * 100, '系统自动转账');
    if (transferRes.errMsg) return { errMsg: transferRes.errMsg }
    res = await db.collection('tb_balance').doc(user_id).get();
  }
  const balance = res.data;
  res = await db.collection('tb_balance_change').aggregate()
    .match(searchData)
    .match(
      _.or([
        { payer_id: user_id },
        { payee_id: user_id },
      ])
    )
    .match({ remark: new RegExp(searchText, 'i') })
    .limit(200)
    .sort({ modified_time: -1 })
    .end();
  return { balance, list: res.list };
}

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const openid = wxContext.OPENID;

  if (event.funcName == 'query') {
    return await searchBalanceList(openid, event.searchText, event.searchData)
  } else if (event.funcName == 'transfer') {
    return await transferBalance(openid, event.payee_id, parseInt(event.price) * 100, event.remark);
  }

  return {
    event,
    // appid: wxContext.APPID,
    // unionid: wxContext.UNIONID,
  }
}